/**
 * 检查对象中是否包含需要的属性, 不包括继承的属性
 *
 * @param {*} obj 要检查的对象
 * @param {string} keyName 需要检查的键值
 * @return {boolean}
 */
function checkProp(obj, keyName) {
  const hasRef = Object.prototype.hasOwnProperty.call(obj, keyName);
  if (!hasRef) {
    console.error(`[form mixin]: component doesn't has required key ${keyName}`);
  }
  return hasRef;
}

/**
 * 生成一个Form Mixin， 封装一些表单通用的方法，适用于el-form
 * @param {string} propName 传递到组件内的表单实体类的名字
 * @param {string} formRefName el-form的ref名
 */
export default function(propName = 'formItem', formRefName = 'form') {
  return {
    methods: {
      /**
       * 更新form组件的表单,向父组件传递事件update事件
       * @param {string} key 要更新的对象key值
       * @param {*} value 要更新对象的value
       */
      updateFormItem(key, value) {
        if (checkProp(this.$props, propName)) {
          this.$emit(`update:${propName}`, {
            ...this[propName],
            [key]: value,
          });
        }
      },
      // 简单封装el-form的clearValidate,供父组件调用
      clearValidate() {
        if (checkProp(this.$refs, formRefName)) {
          this.$refs.form.clearValidate();
        }
      },
      // 简单封装el-form的resetFields,供父组件调用
      resetFields() {
        if (checkProp(this.$refs, formRefName)) {
          this.$refs.form.resetFields();
        }
      },
      /**
       * 简单封装el-form的validate,供父组件调用
       * @param {Function} callback 校验的回调函数
       */
      validate(callback) {
        if (checkProp(this.$refs, formRefName)) {
          this.$refs.form.validate(callback);
        }
      },
    },
  };
}
